package pers.jsan.litheopen.security.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import pers.jsan.litheopen.security.exception.LitheAuthenticationException;
import pers.jsan.litheopen.security.oauth.UserContext;
import pers.jsan.litheopen.security.oauth.UserContextHolder;
import pers.jsan.litheopen.security.prover.AuthenticationManager;
import pers.jsan.litheopen.utils.CodeEnum;
import pers.jsan.litheopen.utils.Result;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class UserOnlineInterceptor implements HandlerInterceptor {

    private final static String AUTHENTICATION = "Authorization";
    private final static String USER_TOKEN_PREFIX = "Bearer ";

    private AuthenticationManager authenticationManager;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
        try {
            if(authenticationManager.isUserOnlineDisable()) {
                throw new LitheAuthenticationException("用户在线校验被禁止");
            }
            String userToken = request.getHeader(AUTHENTICATION);
            if(StringUtils.isEmpty(userToken) || !userToken.contains(USER_TOKEN_PREFIX)) {
                throw new LitheAuthenticationException("用户未登录");
            }
            Object user = authenticationManager.getUser(userToken.replace(USER_TOKEN_PREFIX, ""));
            if(null == user) {
                throw new LitheAuthenticationException("凭证异常");
            }
            authenticationManager.refreshTokenExpires(userToken);
            UserContext userContext = new UserContext();
            userContext.setUserDetail(user);
            UserContextHolder.set(userContext);

        } catch (LitheAuthenticationException e) {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json");
            response.getWriter().write(JSONObject.toJSONString(new Result(CodeEnum.AUTHENTICATION_ERROR.get(), null, e.getMessage())));
            return false;
        }
        return true;
    }

    public UserOnlineInterceptor setAuthenticationManager(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
        return this;
    }

    public AuthenticationManager getAuthenticationManager() {
        return authenticationManager;
    }
}
